-- ShipDisplay
-- Created by chengb Jun/5/2015
-- 幽灵船外观

require "game/ui/module/ship/ShipAnimation"

-- ShipDisplay继承自Node
ShipDisplay = class("ShipDisplay", function()
    return cc.Node:create();
end);

function ShipDisplay.create(classId, actionType)
    return ShipDisplay.new(classId, actionType);
end

-- 构造函数
function ShipDisplay:ctor(classId, actionType)
    -- 记录幽灵船编号
    self.classId = classId;
    
    -- 创建主动画
    local animName = GhostShipM.query(self.classId, "animation");
    local animation = ShipAnimation.create("animation/" .. animName .. ".csb");
    animation:setName("animation");
    self.animation = animation;
    setHighLightMode(self.animation, false);
    self:addChild(animation);

    -- 默认为待机动作
    actionType = actionType or SHIP_ACTION_IDLE;

    -- 播放传入的动作
    self:switchAction(actionType);

    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            if self.animation then
                if self.animation.action then
                    self.animation.action:clearFrameEventCallFunc();
                end

                self.animation:pause();
                self.animation:destroy();               
                self.animation = nil;
            end
        end
    end);      
end

-- 切换怪物动作
function ShipDisplay:switchAction(actionType)
    if SHIP_ACTION_IDLE == actionType then
        -- 待机
        self:gotoIdle();
    elseif SHIP_ACTION_CAST == actionType then
        -- 施法
        self:gotoCast();
    elseif SHIP_ACTION_ATTACK == actionType then
        -- 攻击
        self:gotoAttack();
    else
        -- 暂不支持
        cclog("### 未知的幽灵船动作类型：" .. tostring(actionType));
    end
end

-- 播放待机动作
function ShipDisplay:gotoIdle()
    if self.animation == nil then
        return;
    end

    local actionType = SHIP_ACTION_IDLE;
    if self.actionType ~= actionType then
        self.actionType = actionType;
    end

    -- 获取帧范围和播放速度
    local frameRange = GhostShipM.query(self.classId, "idle_frame"); 
    local speed = GhostShipM.query(self.classId, "idle_speed");

    -- 播放
    self.animation:play(actionType, true, frameRange[1], frameRange[2], speed);

    -- 需要暂停
    if self.needPause then
        self.animation:pause();
    end
end

-- 播放施法
function ShipDisplay:gotoCast()
    if self.animation == nil then
        return;
    end

    local actionType = SHIP_ACTION_CAST;
    if self.actionType ~= actionType then
        self.actionType = actionType;
    end

    -- 获取帧范围和播放速度
    local frameRange = GhostShipM.query(self.classId, "cast_frame"); 
    local speed = GhostShipM.query(self.classId, "cast_speed");
    
    -- 播放
    self.animation:play(actionType, false, frameRange[1], frameRange[2], speed);
    
    -- 注册帧回调函数
    self:registerFrameEvent();
end

-- 播放攻击动作
function ShipDisplay:gotoAttack()
    if self.animation == nil then
        return;
    end

    local actionType = SHIP_ACTION_ATTACK;
    if self.actionType ~= actionType then
        self.actionType = actionType;
    end
    
    -- 获取帧范围和播放速度
    local frameRange = GhostShipM.query(self.classId, "attack_frame"); 
    local speed = GhostShipM.query(self.classId, "attack_speed");

    -- 播放
    self.animation:play(actionType, false, frameRange[1], frameRange[2], speed);
    
    -- 注册帧回调函数
    self:registerFrameEvent()
end

-- 注册帧回调函数
function ShipDisplay:registerFrameEvent()
    -- 移除帧回调处理函数
    self.animation.action:clearFrameEventCallFunc();

    -- 帧回调处理函数
    local function onFrameEvent(frame)
        if nil == frame then
            return;
        end

        -- 使用pilor帧，确保每帧都会有回调过来
        if frame.getEvent and frame:getEvent() == "pilor" then
            -- 帧索引的下标是从0开始的，而配置的下标是从1开始的，故这里要加1
            local frameIndex = frame:getFrameIndex() + 1;
    
            -- 当前帧没有播放完毕
            if not self:isCurrentActionOver(frameIndex) then
                return;
            end
    
            -- 移除帧回调处理函数
            self.animation.action:clearFrameEventCallFunc();
    
            -- 其他情况
            local function callback()
                -- 切换至待机状态
                self:gotoIdle();
            end
    
            performWithDelay(self, callback, 0.1);  
        end    
    end

    -- 设置帧回调处理函数
    self.animation.action:setFrameEventCallFunc(onFrameEvent);
end

---------------------------
-- 获取帧范围
-- @param actionType 动作类型
function ShipDisplay:getFrameRange(actionType)
    if actionType == SHIP_ACTION_IDLE then
        return GhostShipM.query(self.classId, "idle_frame");
    elseif actionType == SHIP_ACTION_CAST then
        return GhostShipM.query(self.classId, "cast_frame");   
    elseif actionType == SHIP_ACTION_ATTACK then
        return GhostShipM.query(self.classId, "attack_frame");
    else
        trace("ShipDisplay", "无法获取帧范围，未知的动作类型：" .. tostring(actionType));
        return nil;             
    end
end

----------------------------
-- 判断当前动作是否已经播完
-- @param curFrameIndex   播放到第几帧
function ShipDisplay:isCurrentActionOver(curFrameIndex)
    local curActionType = self.actionType;
    local endIndex = GhostShipM.query(self.classId, "end_frame_index");
    if curFrameIndex >= endIndex then
        -- 已经到最后一帧了
        return true;
    end

    local range = self:getFrameRange(curActionType);
    if not range then
        return false;
    end

    if curFrameIndex >= range[1] and curFrameIndex < range[2] then
        -- 还没播完
        return false;
    end

    return true;
end

-- 暂停所有动画
function ShipDisplay:pauseActions()
    if self.animation == nil then
        return;
    end
    -- 设置暂停
    self:setNeedPause(true);
    self:gotoIdle();
end

-- 设置是否需要暂停
function ShipDisplay:setNeedPause(needPause)
    --self.needPause = needPause;
end




